package pcmd_fs;

use pcmd_conn_base;
@ISA = ("pcmd_conn_base");

use strict;
use warnings;
    
use pcmd_item;
use pcmd_fs_dir;

use Cwd;
use Cwd 'abs_path';
use File::Spec;
use File::Copy;


#--------------------------
# Init: Initialize class --
#--------------------------
sub init {
    my $self = shift;
    
    $self->SUPER::init(@_);
    
    $self->{root_dir} = File::Spec->rootdir();
};


#-----------
# Connect --
#-----------
sub connect {
    my $self = shift;
    
    $self->{state} = 'connected';
    
    return 0;
};


#------------------
# Open directory --
#------------------
sub open_directory {
    my $self = shift;
    my $path = shift;    
    
    # Get absolute path
    $path = abs_path($path);
    
    if (not (-e $path)) {
        return "Directory '$path' not exists!";
    } elsif (not (-d $path)) {
        return "'$path' is not a directory!";
    } else {
        $self->{directories}{$path} = pcmd_fs_dir->new($self, $path);
        return 0;
    };
};


#----------------
# Get directory --
#----------------
sub get_directory {
    my $self = shift;
    my $path = shift;
    
    # Get absolute path
    $path = abs_path($path);    
    
    return $self->{directories}{$path};
};


#--------------
# Is opened  --
#--------------
sub is_opened {
    my $self = shift;
    my $path = shift;
    
    # Get absolute path
    $path = abs_path($path);    
    
    return (defined $self->{directory}{$path});
};


#-----------------
# Create directory --
#-----------------
sub create_dir {
    my $self = shift;
    my $path = shift;
    my $dirname = shift;
    my $mask = shift;
    
    # Get absolute path
    $path = abs_path($path);   
    
    my $dir_path = File::Spec->catfile( $path, $dirname );
    
    unless (mkdir($dir_path)) {
        return "Can not create new folder: $!";
    } else {
        $self->{directories}{$path}->add_dir($dir_path);
        return 0;
    };
};


#----------
# Delete --
#----------
sub delete {
    my $self = shift;
    my $path = shift;
    my $file  = shift;
    my $rmtree = shift;
    
    # Get absolute path
    $path = abs_path($path);   

    # Remove file
    if ($file->get_type() eq 'dir') {
        if ($rmtree) {
            use File::Path qw(remove_tree);
            
            remove_tree( $file->get_field('abs_path'), {error => \my $err} );
            
            if (@$err) {
                my $error_msg;
                for my $diag (@$err) {
                    my ($file, $message) = %$diag;
                    if ($file eq '') {
                        $error_msg .= "general error: $message\n";
                    } else {
                        $error_msg .= "problem unlinking $file: $message\n";
                    }
                };
                
                return $error_msg;
            } else {
                $self->{directories}{$path}->remove($file->get_name());
                return 0;
            };
        } else {            
            unless (rmdir($file->get_field('abs_path'))) {
                my $name = $file->get_name();
                return "Can not remove '$name' directory: $!";
            } else {
                $self->{directories}{$path}->remove($file->get_name());
                return 0;
            };
        };

    } else {
        unless (unlink($file->get_field('abs_path'))) {
            return "Can not remove $file file: $!";
        } else {
            $self->{directories}{$path}->remove($file->get_name());
            return 0;
        };

        return 0;
    };        
};


1;

